
/**
 * 测试ArrayBuffer
 * https://www.cnblogs.com/chris-oil/p/8615559.html
 */
 function abTest() {
    // ArrayBuffer 申请字节长度内存
    let bf = new ArrayBuffer(40);
    console.log("bf.len", bf.byteLength);
    // slice 拷贝部分
    let newBf = bf.slice(0, 10);
    console.log("newBf.len", newBf.byteLength)

    // 使用DataView 操作ArrayBuffer 支持任意类型的数据
    // 用来操作包含多种数据类型的ArrayBuffer
    let dv = new DataView(bf);
    /**
     *  setInt8：写入1个字节的8位整数。
        setUint8：写入1个字节的8位无符号整数。
        setInt16：写入2个字节的16位整数。
        setUint16：写入2个字节的16位无符号整数。
        setInt32：写入4个字节的32位整数。
        setUint32：写入4个字节的32位无符号整数。
        setFloat32：写入4个字节的32位浮点数。
        setFloat64：写入8个字节的64位浮点数。
        第一个参数 字节序号 表示从哪个字节写入
        第二个参数 写入的数据
        第三个参数 false 大端字节序(默认) true 小端字节序
            写入2个或2个以上字节使用    除Int8和UInt8才有第三个参数
     */
    dv.setInt8(0, 3);
    dv.setInt8(1, 3)
    dv.setInt16(2, 3);
    dv.setInt32(4, 3);
    dv.setInt8(8, 1);
    console.log(bf);
    dv.setInt8(0, 3);
    dv.setInt8(1, 3)
    dv.setInt16(2, 3, true);
    dv.setInt32(4, 3, true);
    dv.setInt8(8, 1);
    console.log(bf);

    /**
     *  getInt8：读取1个字节，返回一个8位整数。
        getUint8：读取1个字节，返回一个无符号的8位整数。
        getInt16：读取2个字节，返回一个16位整数。
        getUint16：读取2个字节，返回一个无符号的16位整数。
        getInt32：读取4个字节，返回一个32位整数。
        getUint32：读取4个字节，返回一个无符号的32位整数。
        getFloat32：读取4个字节，返回一个32位浮点数。
        getFloat64：读取8个字节，返回一个64位浮点数。
        第一个参数 字节序号 从哪个字节开始读取
        第二个参数 false 使用大端字节序, true使用小端字节序
            一次读取2个或2个以上字节使用
     */
    let v1 = dv.getUint8(0);
    let v2 = dv.getUint16(2, true);
    let v3 = dv.getUint32(4, true);
    console.log(v1, v2, v3);

    // 使用单个TypeArray 操作ArrayBuffer 
    /**
     * Int8Array：8位有符号整数，长度1个字节。
        Uint8Array：8位无符号整数，长度1个字节。
        Int16Array：16位有符号整数，长度2个字节。
        Uint16Array：16位无符号整数，长度2个字节。
        Int32Array：32位有符号整数，长度4个字节。
        Uint32Array：32位无符号整数，长度4个字节。
        Float32Array：32位浮点数，长度4个字节。
        Float64Array：64位浮点数，长度8个字节。
        参数格式一: 表示对ArrayBuffer的操作
            第一个参数 ArrayBuffer
            第二个参数 字节序号 从哪里开始 
                16Array 必须从2的倍数开始
                32Array 必须从4的倍数开始
            第上参数  表示包含的数据元素个数
                8Array  n个8Array
                16Array n个16Array
                32Array n个32Array
                默认整个ArrayBuffer
     */
    let ab = new ArrayBuffer(40);
    let i8v = new Int8Array(ab, 1, 1);
    let i16v = new Int16Array(ab, 2, 1)
    let i32v = new Int32Array(ab, 4, 1);
    console.log(i8v, i16v, i32v);

    // TypeArray 可以直接生成内存
    // 参数表示元素个数
    let i8 = new Int8Array(1);
    let i16 = new Int16Array(1);
    let i32 = new Int32Array(1);
    console.log(i8, i16, i32);

    // TypeArray 可以将普通数组转换视图数组
    let t1 = new Uint8Array([1, 2, 3, 4]);
    let a1 = Array.from(t1);
    console.log(t1, a1);

    // TypeArray的操作 类似普通数组
    let i8v2 = new Int8Array(ab, 0, 3);
    let i16v2 = new Int16Array(ab, 0, 3)
    let i32v2 = new Int32Array(ab, 0, 3);
    i8v2[0] = 3;
    i8v2[1] = 3;
    i8v2[2] = 3;
    console.log(ab);
    i16v2[0] = 3;
    i16v2[1] = 3;
    i16v2[2] = 3;
    console.log(ab);
    i32v2[0] = 3;
    i32v2[1] = 3;
    i32v2[2] = 3;
    console.log(ab);

    // buffer属性 返回对应的ArrayBuffer
    console.log(i8v2.buffer);

    // byteOffset 表示从底层的哪个字节序开始
    // byteLength 表示字节长度
    console.log(i16v.byteOffset);
    console.log(i32v2.byteLength);

    // set() 复制数组
    // 整段复制 比单个循环拷贝快
    // 第一个参数 TypeArray 支持不同类型的
    // 第二个参数 字节序号 从哪个字节开始
    let i82 = new Uint8Array(20);
    i82.set(i8v2);
    console.log(i82)
    i82.set(i16v2);
    console.log(i82)

    // 多个TypeArray操作ArrayBuffer
    // 多视图操作 类似多个DataView

    /**
     * 普通数组->TypeArray
     * new TypeArray([1,2,3,4])
     * 
     * TypeArray -> TypeArray2
     * typeArray2.set(typeArray1,2)
     * 
     * UTypeArray与TypeArray的区别
     *      单元素字节长度相同
     *      允许的数字范围不同
     * DataView 实现多种视图的操作
     */
}
export {
    abTest
}
